package com.uniflow.service;

import com.uniflow.entity.UserRole;
import com.uniflow.mapper.UserRoleMapper;
import com.uniflow.util.AuditLogHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 用户角色关联服务层
 * 
 * @author luban
 * @since 1.0.0
 */
@Service
@Transactional
public class UserRoleService {
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private AuditLogHelper auditLogHelper;
    
    /**
     * 根据用户ID查询角色关联列表
     */
    public List<UserRole> getUserRoles(String userId) {
        return userRoleMapper.selectByUserId(userId);
    }
    
    /**
     * 根据角色ID查询用户关联列表
     */
    public List<UserRole> getRoleUsers(String roleId) {
        return userRoleMapper.selectByRoleId(roleId);
    }
    
    /**
     * 检查用户是否有指定角色
     */
    public boolean hasUserRole(String userId, String roleId) {
        return userRoleMapper.hasUserRole(userId, roleId);
    }
    
    /**
     * 查询用户的角色ID列表
     */
    public List<String> getUserRoleIds(String userId) {
        return userRoleMapper.selectRoleIdsByUserId(userId);
    }
    
    /**
     * 查询角色的用户ID列表
     */
    public List<String> getRoleUserIds(String roleId) {
        return userRoleMapper.selectUserIdsByRoleId(roleId);
    }
    
    /**
     * 分配角色给用户
     */
    @Transactional
    public UserRole assignRole(String userId, String roleId, String assignedBy, String assignedByName) {
        // 检查是否已存在
        if (hasUserRole(userId, roleId)) {
            throw new RuntimeException("用户已拥有该角色");
        }
        
        UserRole userRole = new UserRole(userId, roleId, assignedBy, assignedByName);
        userRoleMapper.insert(userRole);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "ASSIGN_ROLE",
            "user_role",
            userId + "-" + roleId,
            "分配角色",
            "success",
            assignedBy
        );
        
        return userRole;
    }
    
    /**
     * 批量分配角色给用户
     */
    @Transactional
    public void assignRoles(String userId, List<String> roleIds, String assignedBy, String assignedByName) {
        for (String roleId : roleIds) {
            if (!hasUserRole(userId, roleId)) {
                assignRole(userId, roleId, assignedBy, assignedByName);
            }
        }
    }
    
    /**
     * 移除用户角色
     */
    @Transactional
    public void removeRole(String userId, String roleId, String operatorId) {
        // 检查是否存在
        if (!hasUserRole(userId, roleId)) {
            throw new RuntimeException("用户没有该角色");
        }
        
        userRoleMapper.deleteByUserIdAndRoleId(userId, roleId);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "REMOVE_ROLE",
            "user_role",
            userId + "-" + roleId,
            "移除用户角色: " + roleId,
            "success",
            operatorId
        );
    }
    
    /**
     * 批量移除用户角色
     */
    @Transactional
    public void removeRoles(String userId, List<String> roleIds, String operatorId) {
        for (String roleId : roleIds) {
            if (hasUserRole(userId, roleId)) {
                removeRole(userId, roleId, operatorId);
            }
        }
    }
    
    /**
     * 更新用户的所有角色
     */
    @Transactional
    public void updateUserRoles(String userId, List<String> roleIds, String operatorId, String operatorName) {
        // 先删除用户的所有角色
        userRoleMapper.deleteByUserId(userId);
        
        // 再分配新角色
        if (roleIds != null && !roleIds.isEmpty()) {
            assignRoles(userId, roleIds, operatorId, operatorName);
        }
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "UPDATE_USER_ROLES",
            "user",
            userId,
            "更新用户角色，新角色数量: " + (roleIds != null ? roleIds.size() : 0),
            "success",
            operatorId
        );
    }
    
    /**
     * 删除用户的所有角色
     */
    @Transactional
    public void removeAllUserRoles(String userId, String operatorId) {
        int deletedCount = userRoleMapper.deleteByUserId(userId);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "REMOVE_ALL_ROLES",
            "user",
            userId,
            "移除用户的所有角色，共移除: " + deletedCount + " 个角色",
            "success",
            operatorId
        );
    }
    
    /**
     * 删除角色的所有用户关联
     */
    @Transactional
    public void removeAllRoleUsers(String roleId, String operatorId) {
        int deletedCount = userRoleMapper.deleteByRoleId(roleId);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "REMOVE_ROLE_USERS",
            "role",
            roleId,
            "移除角色的所有用户关联，共移除: " + deletedCount + " 个用户",
            "success",
            operatorId
        );
    }
    
    /**
     * 查询用户角色关联总数
     */
    public Long getTotalCount() {
        return userRoleMapper.selectCount();
    }
    
    /**
     * 查询指定用户的角色数量
     */
    public Long getUserRoleCount(String userId) {
        return userRoleMapper.selectUserRoleCount(userId);
    }
    
    /**
     * 查询指定角色的用户数量
     */
    public Long getRoleUserCount(String roleId) {
        return userRoleMapper.selectRoleUserCount(roleId);
    }
    
    /**
     * 查询角色分布统计
     */
    public List<Map<String, Object>> getRoleDistributionStats() {
        return userRoleMapper.selectRoleDistributionStats();
    }
    
    /**
     * 查询用户角色统计
     */
    public List<Map<String, Object>> getUserRoleStats() {
        return userRoleMapper.selectUserRoleStats();
    }
    
    /**
     * 查询最近分配的角色
     */
    public List<UserRole> getRecentAssigned(Integer limit) {
        return userRoleMapper.selectRecentAssigned(limit);
    }
    
    /**
     * 查询指定时间段内的角色分配记录
     */
    public List<UserRole> getAssignedInPeriod(LocalDateTime startTime, LocalDateTime endTime) {
        return userRoleMapper.selectAssignedInPeriod(startTime, endTime);
    }
    
    /**
     * 查询没有角色的用户列表
     */
    public List<String> getUsersWithoutRole() {
        return userRoleMapper.selectUsersWithoutRole();
    }
    
    /**
     * 查询没有用户的角色列表
     */
    public List<String> getRolesWithoutUser() {
        return userRoleMapper.selectRolesWithoutUser();
    }
    
    /**
     * 查询用户角色变更历史
     */
    public List<Map<String, Object>> getUserRoleHistory(String userId) {
        return userRoleMapper.selectUserRoleHistory(userId);
    }
    
    /**
     * 查询角色分配者统计
     */
    public List<Map<String, Object>> getAssignerStats() {
        return userRoleMapper.selectAssignerStats();
    }
    
    /**
     * 检查角色分配冲突
     */
    public List<Map<String, Object>> checkRoleConflicts(String userId, List<String> roleIds) {
        return userRoleMapper.checkRoleConflicts(userId, roleIds);
    }
    
    /**
     * 复制用户角色
     */
    @Transactional
    public void copyUserRoles(String sourceUserId, String targetUserId, String operatorId, String operatorName) {
        // 获取源用户的角色
        List<String> sourceRoleIds = getUserRoleIds(sourceUserId);
        
        if (sourceRoleIds.isEmpty()) {
            throw new RuntimeException("源用户没有任何角色");
        }
        
        // 为目标用户分配相同角色
        updateUserRoles(targetUserId, sourceRoleIds, operatorId, operatorName);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "COPY_USER_ROLES",
            "user",
            targetUserId,
            "从用户 " + sourceUserId + " 复制角色到用户 " + targetUserId + "，共复制 " + sourceRoleIds.size() + " 个角色",
            "success",
            operatorId
        );
    }
    
    /**
     * 交换用户角色
     */
    @Transactional
    public void swapUserRoles(String userId1, String userId2, String operatorId, String operatorName) {
        // 获取两个用户的角色
        List<String> user1RoleIds = getUserRoleIds(userId1);
        List<String> user2RoleIds = getUserRoleIds(userId2);
        
        // 交换角色
        updateUserRoles(userId1, user2RoleIds, operatorId, operatorName);
        updateUserRoles(userId2, user1RoleIds, operatorId, operatorName);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "SWAP_USER_ROLES",
            "user",
            userId1 + "-" + userId2,
            "交换用户 " + userId1 + " 和用户 " + userId2 + " 的角色",
            "success",
            operatorId
        );
    }
}